package order

import (
	"context"
	"strings"

	"mall/common/globalkey"
	"mall/common/resultx"
	"mall/service/backend/common/i18n"
	"mall/service/order/model"
	"mall/service/order/rpc/internal/svc"
	"mall/service/order/rpc/internal/utils/errorhandler"
	"mall/service/order/rpc/types/order"

	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateTradeStateBatchLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewUpdateTradeStateBatchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateTradeStateBatchLogic {
	return &UpdateTradeStateBatchLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *UpdateTradeStateBatchLogic) UpdateTradeStateBatch(in *order.UpdateTradeStateBatchReq) (*order.BaseResp, error) {
	if len(in.Data) == 0 {
		return &order.BaseResp{}, nil
	}

	tx, err := l.svcCtx.DB.BeginTx(l.ctx, nil)
	if err != nil {
		return nil, resultx.StatusError(resultx.ORDER_CREATE_FAILED, "")
	}

	for _, v := range in.Data {
		var id uint64
		rel := &model.OrderRel{}
		if (v.Id == nil || *v.Id == 0) && (v.Sn == nil || len(strings.TrimSpace(*v.Sn)) == 0) {
			continue
		}
		if v.TradeState == nil || *v.TradeState == 0 {
			continue
		}
		if v.Id != nil && *v.Id > 0 {
			id = *v.Id
		} else if v.Sn != nil && len(strings.TrimSpace(*v.Sn)) > 0 {
			filterMap := make(map[string]map[string][]any)
			filterMap[model.OrderColumns.OrderSN] = map[string][]any{
				"equalTo": {strings.TrimSpace(*v.Sn)},
			}
			ret, _, err := l.svcCtx.Order.GetList(l.ctx, model.M{}, -1, filterMap)
			if err != nil {
				// return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				logx.Errorw("BackendGetOrderList GetList statistic err", logx.Field("detail", err.Error()))
			}
			if len(ret) > 0 && ret[0] != nil && ret[0].ID > 0 {
				id = ret[0].ID
			}
		}
		trade, err := l.svcCtx.Order.FindOneNoCache(l.ctx, nil, id)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(v.OrderItem) > 0 {
			var ids []any
			var itemIdMap = make(map[uint64]*model.OrderItem)

			for _, item := range v.OrderItem {
				if item.Id != nil && *item.Id > 0 {
					ids = append(ids, *item.Id)
				}
			}
			filterMap := make(map[string]map[string][]any)
			filterMap[model.OrderItemColumns.OrderID] = map[string][]any{
				"in": ids,
			}
			ret, _, err := l.svcCtx.Order.GetItemList(l.ctx, model.M{}, -1, filterMap)
			if err != nil {
				// return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				logx.Errorw("BackendGetOrderList GetList statistic err", logx.Field("detail", err.Error()))
			}

			for _, item := range ret {
				if _, ok := itemIdMap[item.OrderItemID]; !ok {
					itemIdMap[item.OrderItemID] = item
				}
			}

			for _, item := range v.OrderItem {
				if orderItem, ok := itemIdMap[*item.Id]; ok {
					if item.TradeState != nil {
						orderItem.Status = uint8(*item.TradeState)
					}
					rel.Items = append(rel.Items, orderItem)
				}
			}
		}

		//todo 快递单号 逻辑待修改
		if v.Waybill != nil && len(strings.TrimSpace(*v.Waybill)) > 0 {
			//filterMap := make(map[string]map[string][]any)
			//filterMap[model.OrderShipmentColumns.No] = map[string][]any{
			//	"equalTo": {id},
			//}
			//ret, _, err := l.svcCtx.Order.GetShipmentList(l.ctx, model.M{}, -1, filterMap)
			//if err != nil {
			//	// return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
			//	logx.Errorw("BackendGetOrderList GetList statistic err", logx.Field("detail", err.Error()))
			//}
			//rel.Shipments
		}

		status := *v.TradeState
		switch uint32(trade.TradeState) {
		case globalkey.OrderTradeStateNotPay:
			if status == globalkey.OrderTradeStateUserCancelled || status == globalkey.OrderTradeStateAutoCancelled || status == globalkey.OrderTradeStateAdminCancelled {
				trade.TradeState = uint16(status) // 取消订单0
				err = l.svcCtx.Order.Update(l.ctx, tx, trade, rel)
				if err != nil {
					return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				}
			}
		case globalkey.OrderTradeStateUserCancelled, globalkey.OrderTradeStateAutoCancelled, globalkey.OrderTradeStateAdminCancelled:
			if status == globalkey.OrderTradeStateUserDeleted || status == globalkey.OrderTradeStateAdminDeleted {
				trade.TradeState = uint16(status) // 删除订单
				err = l.svcCtx.Order.Update(l.ctx, tx, trade, rel)
				if err != nil {
					return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				}
			}
		case globalkey.OrderTradeStatePaid, globalkey.OrderTradeStateShipping:
			if status == globalkey.OrderTradeStateShipped {
				trade.TradeState = uint16(status) // 订单已发货
				err = l.svcCtx.Order.Update(l.ctx, tx, trade, rel)
				if err != nil {
					return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				}
			}
		case globalkey.OrderTradeStateShipped:
			// fmt.Println("触发已收货")
			if status == globalkey.OrderTradeStateConfirmed || status == globalkey.OrderTradeStateAutoConfirmed {
				trade.TradeState = uint16(status) // 订单已收货
				err = l.svcCtx.Order.Update(l.ctx, tx, trade, rel)
				if err != nil {
					return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
				}
			}
		}
	}
	tx.Commit()

	return &order.BaseResp{
		Msg: i18n.UpdateSuccess,
	}, nil
}
